home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / C / hf^k-6.dms / in.adf / Install.run / GOLDEDDATA / developer / examples / api / rexx / lib.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-11  |  4.4 KB  |  168 lines

  1. /*
  2.  *  LIB.C
  3.  *
  4.  *  Basic Library Resource Handling
  5.  *
  6.  *  NOTE: all data declarations should be initialized since we skip
  7.  *        normal C startup code (unless initial value is don't care)
  8.  *
  9.  *  WARNING: arguments are passed in certain registers from the assembly
  10.  *        tag file, matched to how they are declared below.  Do not change
  11.  *        the argument declarations!
  12.  */
  13.  
  14. #include "defs.h"
  15.  
  16. Prototype LibCall struct Library *LibInit   (__D0 BPTR);
  17. Prototype LibCall struct Library *LibOpen   (__D0 long, __A0 struct Library *);
  18. Prototype LibCall long            LibClose  (__A0 struct Library *);
  19. Prototype LibCall long            LibExpunge(__A0 struct Library *);
  20.  
  21. struct Library  *LibBase       = NULL;
  22. struct ExecBase *SysBase       = NULL;
  23. struct Library  *DOSBase       = NULL;
  24. struct Library  *IntuitionBase = NULL;
  25.  
  26. BPTR SegList = 0;
  27.  
  28. /*
  29.  *    The Initialization routine is given only a seglist pointer.  Since
  30.  *    we are NOT AUTOINIT we must construct and add the library ourselves
  31.  *    and return either NULL or the library pointer.  Exec has Forbid()
  32.  *    for us during the call.
  33.  *
  34.  *    We use an extended library structure to allow identification as an
  35.  *    API client
  36.  */
  37.  
  38. LibCall struct Library *
  39. LibInit(__D0 BPTR segment)
  40. {
  41.     struct Library *lib;
  42.  
  43.     static const long Vectors[] = {
  44.  
  45.         (long)ALibOpen,
  46.         (long)ALibClose,
  47.         (long)ALibExpunge,
  48.         (long)ALibReserved,
  49.         (long)APIMountClient,
  50.         (long)APICloseClient,
  51.         (long)APIBriefClient,
  52.         (long)APIFree,
  53.         -1
  54.     };
  55.  
  56.     SysBase = (struct ExecBase *)*(long *)4;
  57.  
  58.     if (DOSBase = OpenLibrary("dos.library", 0)) {
  59.  
  60.         if (IntuitionBase = OpenLibrary("intuition.library", 0)) {
  61.  
  62.             if (LibBase = lib = MakeLibrary((APTR)Vectors, NULL, NULL, sizeof(struct APIBase), NULL)) {
  63.  
  64.                 lib->lib_Node.ln_Type = NT_LIBRARY;
  65.                 lib->lib_Node.ln_Name = LibName;
  66.                 lib->lib_Flags        = LIBF_CHANGED | LIBF_SUMUSED;
  67.                 lib->lib_Version      = 37;
  68.                 lib->lib_Revision     = 0;
  69.                 lib->lib_IdString     = (APTR)LibId;
  70.  
  71.                 ((struct APIBase *)lib)->Magic = API_MAGIC;
  72.  
  73.                 SegList = segment;
  74.  
  75.                 AddLibrary(lib);
  76.  
  77.                 InitC();
  78.  
  79.                 return(lib);
  80.             }
  81.         }
  82.     }
  83.  
  84.     return(NULL);
  85. }
  86.  
  87. /*
  88.  *    Open is given the library pointer and the version request.  Either
  89.  *    return the library pointer or NULL.  Remove the DELAYED-EXPUNGE flag.
  90.  *    Exec has Forbid() for us during the call.
  91.  */
  92.  
  93. LibCall struct Library *
  94. LibOpen(__D0 long version, __A0 struct Library *lib)
  95. {
  96.     ++lib->lib_OpenCnt;
  97.  
  98.     lib->lib_Flags &= ~LIBF_DELEXP;
  99.  
  100.     return(lib);
  101. }
  102.  
  103. /*
  104.  *    Close is given the library pointer and the version request.  Be sure
  105.  *    not to decrement the open count if already zero.  If the open count
  106.  *    is or becomes zero AND there is a LIBF_DELEXP, we expunge the library
  107.  *    and return the seglist.  Otherwise we return NULL.
  108.  *
  109.  *    Note that this routine never sets LIBF_DELEXP on its own.
  110.  *
  111.  *    Exec has Forbid() for us during the call.
  112.  */
  113.  
  114. LibCall long
  115. LibClose(__A0 struct Library *lib)
  116. {
  117.     if (lib->lib_OpenCnt && --lib->lib_OpenCnt)
  118.         return(NULL);
  119.  
  120.     if (lib->lib_Flags & LIBF_DELEXP)
  121.         return(LibExpunge(lib));
  122.  
  123.     return(NULL);
  124. }
  125.  
  126. /*
  127.  *    We expunge the library and return the Seglist ONLY if the open count
  128.  *    is zero.  If the open count is not zero we set the DELAYED-EXPUNGE
  129.  *    flag and return NULL.
  130.  *
  131.  *    Exec has Forbid() for us during the call.  NOTE ALSO that Expunge
  132.  *    might be called from the memory allocator and thus we CANNOT DO A
  133.  *    Wait() or otherwise take a long time to complete (straight from RKM).
  134.  *
  135.  *    Apparently RemLibrary(lib) calls our expunge routine and would
  136.  *    therefore freeze if we called it ourselves.  As far as I can tell
  137.  *    from RKM, LibExpunge(lib) must remove the library itself as shown
  138.  *    below.
  139.  */
  140.  
  141. LibCall long
  142. LibExpunge(__A0 struct Library *lib)
  143. {
  144.     if (lib->lib_OpenCnt) {
  145.  
  146.         lib->lib_Flags |= LIBF_DELEXP;
  147.         return(NULL);
  148.     }
  149.  
  150.     Remove(&lib->lib_Node);
  151.  
  152.     FreeMem((char *)lib - lib->lib_NegSize, lib->lib_NegSize + lib->lib_PosSize);
  153.  
  154.     if (IntuitionBase) {
  155.  
  156.         CloseLibrary((struct Library *)IntuitionBase);
  157.         IntuitionBase = NULL;
  158.     }
  159.  
  160.     if (DOSBase) {
  161.  
  162.         CloseLibrary((struct Library *)DOSBase);
  163.         DOSBase = NULL;
  164.     }
  165.  
  166.     return((long)SegList);
  167. }
  168.